import java.io.*;
import java.text.ParseException;
import java.util.*;


/**
 * Class StudentInput is an input class for assignment submission and view assignments status.
 */
class StudentInput {
	private String studentID;
	private String password;
	private String option; 
	private String subjectID;
	private String assignmentID;
	private String submissionFile;
	
	public StudentInput(String[] data) {
		if (data.length > 1) {
			studentID=data[0];
			password=data[1];
			option=data[2];
			if (option.equals("1")) {
				subjectID=data[3];
				assignmentID=data[4];
				submissionFile=data[5];
			}
			else 
			{
				subjectID=data[3];
				assignmentID=data[4];
			}				
		}
	}
	
	public String getStudentID() {
		return studentID;
	}
	public String getPassword() {
		return password;
	}
	public String getOption() {
		return option;
	}
	public String getSubjectID() {
		return subjectID;
	}
	public String getAssignmentID() {
		return assignmentID;
	}
	public String getSubmissionFile() {
		return submissionFile;
	}
}


/**
 * Class Assignment for subject's assignment data
 */
class Assignment {
//	A01,Agile Assignment 1,HIT8098,2010-03-11 17:30:00
	private String assignmentID;
	private String title;
	private String subjectID;
	private String dueDate;

	public Assignment(String[] data) {
		assignmentID=data[0];
		title=data[1];
		subjectID=data[2];
		dueDate=data[3];
	}

	public String getAssignmentID() {
		return assignmentID;
	}
	public String getSubjectID() {
		return subjectID;
	}
	public String getDueDate() {
		return dueDate;
	}
}


/**
 * Class Enrollment for student's enrollment data to certain subject 
 */
class Enrollment {
// 333,HIT8098
	private String studentID;
	private String subjectID;

	public Enrollment(String[] data) {
		studentID=data[0];
		subjectID=data[1];
	}
	public String getStudentID() {
		return studentID;
	}
	public String getSubjectID() {
		return subjectID;
	}
}


/**
 * Class Submission for student's assignment submission data 
 */
class Submission {
	private String submissionID;
	private String studentID;
	private String subjectID;
	private String assignmentID;
	private String dateTimeSubmission;
	private String submissionFile;
	private String latePenalty;
	private String markStatus;
	
	public Submission(String[] data) {
		if (data.length > 1) {
			submissionID=data[0];
		    studentID=data[1];
		    subjectID=data[2];
		    assignmentID=data[3];
		    dateTimeSubmission=data[4];
		    submissionFile=data[5];
		    latePenalty=data[6];
		    markStatus=data[7];
		}
	}
	
	public String getSubmissionID() { 
		return submissionID; 
	}
	public String getStudentID() { 
		return studentID; 
	}
	public String getSubjectID() {
		return subjectID; 
	}
	public String getAssignmentID() {
		return assignmentID; 
	}
	public String getDateTimeSubmission() {
		return dateTimeSubmission;
	}
	public String getSubmissionFile() {
		return submissionFile;
	}
	public String getLatePenalty() {
		return latePenalty;
	}
	public String getMarkStatus() {
		return markStatus;
	}
}



/**
 * Class submissionMain is the main program of student's submission process 
 * @throws IOException, ParseEcxeption
 */
public class SubmissionMain {
	ArrayList<String> data;
	ArrayList<String> result;
	ArrayList<StudentInput> stdInput = new ArrayList<StudentInput>();
	ArrayList<Enrollment> enrollmentData = new ArrayList<Enrollment>();
	ArrayList<Assignment> assignmentData = new ArrayList<Assignment>();
	ArrayList<Submission> submissionData = new ArrayList<Submission>();
    static String INPUT_FILE;
    static final String LOGIN_FILE = "login.txt";
    static final String ENROLLMENT_FILE = "enrollment.txt";
    static final String ASSIGNMENT_FILE = "assignment.txt";
    static final String SUBMISSION_FILE = "submission.txt";
    int noReceipt=0;

	public SubmissionMain(String inputFile) throws IOException, ParseException {
        INPUT_FILE = inputFile;
		initObject();
		process(stdInput);
	}
	

/**
 * Get the data from text file and object initialization  
 */
	public void initObject() throws IOException {
		data = new ArrayList<String>();
        data.clear();
		readFile.readFrom(INPUT_FILE, data);
        for (int i=0; i<data.size(); i++)
            if (data.get(i).split(",").length > 1)
            {
        	stdInput.add(new StudentInput(data.get(i).split(",")));
            }

		data = new ArrayList<String>();
		readFile.readFrom(ENROLLMENT_FILE, data);
        for (int i=0; i<data.size(); i++) {
        	enrollmentData.add(new Enrollment(data.get(i).split(",")));
        }

		data = new ArrayList<String>();
		readFile.readFrom(ASSIGNMENT_FILE, data);
        for (int i=0; i<data.size(); i++) {
        	assignmentData.add(new Assignment(data.get(i).split(",")));
        }

        data = new ArrayList<String>();
		readFile.readFrom(SUBMISSION_FILE, data);
        noReceipt=data.size();
	}
	

/**
 * Process for student's submission and view status assignment  
 */
	public void process(ArrayList<StudentInput> stdInput) throws IOException, ParseException
    {
        for (int i=0; i<stdInput.size(); i++) {
        	if (checkLogin(stdInput.get(i))) {
        		if (((stdInput.get(i)).getOption().equals("1"))) {
            		result = new ArrayList<String>();
            	    submitAssignment(stdInput.get(i));
        		}
        		else
            		if (((stdInput.get(i)).getOption().equals("2"))) 
                		viewStatus(stdInput.get(i));
            		else {
            			result = new ArrayList<String>();
               			result.add("Option Data:"+(stdInput.get(i)).getOption()+" Is Not Valid!");
                	    writeFile.writeTo(SUBMISSION_FILE, result, true);                    		
            		}
        	}
        	else {
    			result = new ArrayList<String>();
       			result.add("Login Data Is Not Valid!");
        	    writeFile.writeTo(SUBMISSION_FILE, result, true);                    		
        	}
        }
    }
    
/**
 * Match the login input with the login data in the text file  
 */
	    public boolean checkLogin(StudentInput std) throws IOException {
			data = new ArrayList<String>();
	        readFile.readFrom(LOGIN_FILE, data);

	        for (int i = 0; i< data.size(); i++) {
	            String[] identity = data.get(i).split(",");
	            if ( std.getStudentID().toUpperCase().equals(identity[0].toUpperCase()) && 
	            	 std.getPassword().equals(identity[1]) )
	            	return true;
	        }
	        return false;
	    }	

/**
 * Student's assignment submission  
 */
	public void submitAssignment(StudentInput std) throws IOException, ParseException {
            if (findEnrollment(std)) {
                if (findAssignment(std)!=null) {
                    if (getDate.elapsedDay((findAssignment(std)).getDueDate()) > 5) {
                            result.add("Submission Is More Than 5 days!");
                    }
                    else
                    {
                        String resultStr=SubmissionReceipt() + "," + std.getStudentID()+","+std.getSubjectID()+","+std.getAssignmentID()+","+getDate.dateandtime()+","+std.getSubmissionFile();
                        resultStr += ",-" + getDate.elapsedDay((findAssignment(std)).getDueDate())*10 + "%,N";
                        result.add(resultStr);
                    }
                }
                else
                    result.add("Assignment ID Is Not Valid!");
            }
            else
                result.add("StudentID:"+std.getStudentID()+" Is Not Enrolled to This SubjectID:"+std.getSubjectID()+"!");
            writeFile.writeTo(SUBMISSION_FILE, result, true);
	}
	

/**
 * Generate receipt for submission  
*/
	private String SubmissionReceipt() {
    	String tempno = "000";
    	noReceipt++;
    	return "S" + tempno.substring(0, tempno.length() - (Integer.toString(noReceipt)).length()) + Integer.toString(noReceipt);
    }
	
/**
 * Find enrollment data for a particular student  
 */
	private boolean findEnrollment(StudentInput std) {
		for (Enrollment en : enrollmentData) {
			if (en.getStudentID().equals(std.getStudentID()) 
				&& en.getSubjectID().toUpperCase().equals(std.getSubjectID().toUpperCase())) {
			     return true;
			}
		}
		return false;
	}

/**
 * Find assignment data for a particular student  
 */
	private Assignment findAssignment(StudentInput std) {
		for (Assignment as : assignmentData) {
	        if (as.getAssignmentID().equals(std.getAssignmentID()) &&  
	        	as.getSubjectID().equals(std.getSubjectID())) {
	        	return as;
	        }
		}
		return null;
	}	


/**
 *  Download assignment feedback for a specific assignment of a student
 *
 */
public void assignmentFeedback(StudentInput std, ArrayList<String> data ) throws IOException
{
        data.clear();
        String fileName = std.getAssignmentID() + std.getSubjectID() + "_" + std.getStudentID();

        for (Submission sub : submissionData) {
            if (std.getStudentID().equals(sub.getStudentID()) &&
             (std.getSubjectID().equals(sub.getSubjectID()) ) &&
             (  std.getAssignmentID().equals(sub.getAssignmentID())  )   )
             {
                    if (sub.getMarkStatus().toUpperCase().equals("Y"))
                    {
                        readFile.readFrom(fileName+".txt", data);
                    }
                    else
                    {
                        data.add("Assignment is not marked");
                    }
                    break;
             }
        }

        if (data.isEmpty())
	   data.add("Assignment is not found");

        writeFile.writeTo(fileName + "MarkSheet.txt", data, false);        
    }

/**
 * Download all assignments of a student and put them to result
 *
 */
    public void getAssignmentStatus(StudentInput std) throws IOException
    {
        //StudentID, subject, AssignmentID, submissionStatus, submissionFile, dateTimeSubmission, deadLine, latePenaltyPercentage
	result = new ArrayList<String>();
        for (Submission sub : submissionData) {
            if (std.getStudentID().equals(sub.getStudentID())) {
                String resultStr = sub.getStudentID() + "," + sub.getSubmissionID() + "," + sub.getSubjectID() + "," + sub.getAssignmentID() + ",";
                if (sub.getMarkStatus().toUpperCase().equals("Y"))
                        resultStr += "Marked";
                else
                        resultStr += "Not Marked";
                resultStr += "," + sub.getSubmissionFile() + "," + sub.getDateTimeSubmission() + "," + sub.getLatePenalty();
                result.add(resultStr);
            }
        }

        if (result.size()==0)
            result.add("Assignments Data for this Student ID:"+std.getStudentID()+" is Not Found!");

        writeFile.writeTo(std.getStudentID()+".txt", result, false);

    }
    
/**
 * View the status of all student's submitted work  
 */
    public void viewStatus(StudentInput std) throws IOException {
	data = new ArrayList<String>();
	readFile.readFrom(SUBMISSION_FILE, data);
        for (int i=0; i<data.size(); i++) {
        	submissionData.add(new Submission(data.get(i).split(",")));
        }                

        // always display all assignments of a student regardless they want to view a specific assignment or not
        getAssignmentStatus( std );

        // display feedback of an assignment that student chose to view
        if (std.getSubjectID() != null )
             assignmentFeedback(std, data );        
    }
    
    public static void main(String[] args) throws IOException, ParseException {
    	if (args.length > 0) {
        	new SubmissionMain(args[0]);
    	}
    }
}
